package triStorage;

import utils.Constants;
import utils.Converter;

import java.util.concurrent.locks.*;

public class Page {
	
	public byte[] bytes;
	
	public int pageId;
	
	private ReadWriteLock rwlock;
	private Lock rlock;
	private Lock wlock;
	
	public Page(int PAGE_SIZE) {
		bytes = new byte[PAGE_SIZE];
		rwlock = new ReentrantReadWriteLock();
		rlock = rwlock.readLock();
		wlock = rwlock.writeLock();
	}
	
	public int writeInt(int offset, int value) {
		wlock.lock();
		try {
			if (offset + Constants.INT_SIZE > bytes.length)
				//throw PageAccessException.error;
				return Constants.W_ERROCODE;
			Converter.Int2Bytes(value, bytes, offset);
			return 1;
		}
		finally {
			wlock.unlock();
		}
	}
	
	public int writeLong(int offset, long value) {
		wlock.lock();
		try {
			if (offset + Constants.LONG_SIZE > bytes.length)
				//throw PageAccessException.error;
				return Constants.W_ERROCODE;
			Converter.Long2Bytes(value, bytes, offset);
			return 1;
		}
		finally {
			wlock.unlock();
		}
	}

	public int writeBytes(int offset, byte[] value, int start, int length) {
		wlock.lock();
		try {
			int i;
			for (i = 0; i < length && offset + i < bytes.length; ++i)
				bytes[offset + i] = value[start + i];
			return i;
		}
		finally {
			wlock.unlock();
		}
	}

	public Integer readInt(int offset) {
		rlock.lock();
		try {
			if (offset + Constants.INT_SIZE > bytes.length)
				//throw PageAccessException.error;
				return null;
			return Converter.Bytes2Int(bytes, offset);
		}
		finally {
			rlock.unlock();
		}
	}
	
	public Long readLong(int offset) {
		rlock.lock();
		try {
			if (offset + Constants.LONG_SIZE > bytes.length)
				//throw PageAccessException.error;
				return null;
			return Converter.Bytes2Long(bytes, offset);
		}
		finally {
			rlock.unlock();
		}
	}

	public int readBytes(int offset, byte[] value, int start, int length) {
		rlock.lock();
		try {
			int i;
			//System.out.println("readBytes " + start + " " + length);
			for (i = 0; i < length && offset + i < bytes.length; ++i)
				value[start + i] = bytes[offset + i];
			return i;
		}
		finally {
			rlock.unlock();
		}
	}
	
}
